package com.hopedove.workshop.viewmodel.shiftchange

import androidx.databinding.ObservableField
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import androidx.lifecycle.viewModelScope
import com.hadilq.liveevent.LiveEvent
import com.hopedove.data.Datetime
import com.hopedove.net.ApiCallResult
import com.hopedove.repository.CommonRepository
import com.hopedove.viewmodel.BaseViewModel
import com.hopedove.viewmodel.CommonEvent
import com.hopedove.workshop.api.ShiftChangeQueryItem
import com.hopedove.workshop.api.ShiftChangeSaveItem
import com.hopedove.workshop.api.WorkShopItem
import com.hopedove.workshop.api.WorkshopApi
import com.hopedove.workshop.data.pojo.ObservableShiftQueryItem
import com.hopedove.workshop.repository.WorkshopUserRepository
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch

class ShiftChangeQueryViewModel(
    private val api: WorkshopApi,
    private val commonRepo: CommonRepository,
    private val userRepo: WorkshopUserRepository
) : BaseViewModel() {

    private var startDate = commonRepo.getServerDateTime().dateFormatEn()
    val displayStartDate = MutableLiveData("日期: $startDate")

    private var endDate = commonRepo.getServerDateTime().dateFormatEn()
    val displayEndDate = MutableLiveData("日期: $endDate")

    val displayName = MutableLiveData("记录人：${userRepo.getSignedInUserName()}")
    val fromMachineNo = MutableLiveData("")
    val toMachineNo = MutableLiveData("")
    val clothNo = MutableLiveData("")

    private val _pickStartDate = LiveEvent<Datetime>()
    val pickStartDate: LiveData<Datetime> = _pickStartDate

    private val _pickEndDate = LiveEvent<Datetime>()
    val pickEndDate: LiveData<Datetime> = _pickEndDate

    private val _workshops = MutableLiveData<List<WorkShopItem>>()
    val workshops: LiveData<List<String>> = Transformations.map(_workshops) { list ->
        list.map { it.name }
    }

    val selectedWorkshopIndex = MutableLiveData(-1)

    private var queryList = MutableLiveData<List<ShiftChangeQueryItem>>()
    val queryItems: LiveData<List<ObservableShiftQueryItem>> =
        Transformations.map(queryList) { list ->
            list.map {
                ObservableShiftQueryItem(
                    it.clothNo,
                    it.machineNo,
                    it.primaryId,
                    ObservableField(it.remark),
                    it.info ?: "",
                    enableCheck = it.state == "0"
                )
            }
        }

    private var saveJob: Job? = null
    private var deleteJob: Job? = null
    private var queryJob: Job? = null

    override fun load() = viewModelScope.launch {
        getWorkshops()
    }

    fun onPickStartDateClicked() {
        val curDate = startDate
        _pickStartDate.value = Datetime.parseEnFormat(curDate)
    }

    fun onPickEndDateClicked() {
        val curDate = endDate
        _pickEndDate.value = Datetime.parseEnFormat(curDate)
    }

    // 更新日期
    fun updateStartDate(datetime: Datetime) {
        startDate = datetime.dateFormatEn()
        displayStartDate.postValue("日期: $startDate")
    }

    // 更新结束日期
    fun updateEndDate(datetime: Datetime) {
        endDate = datetime.dateFormatEn()
        displayEndDate.postValue("日期: $endDate")
    }

    fun onQueryClick() {
        if (queryJob?.isCompleted?.not() == true) return

        val workshopId = getWorkshopId()
        val cloth = clothNo.value ?: ""
        val fromMachine = fromMachineNo.value ?: ""
        val toMachine = toMachineNo.value ?: ""

        val userSession = userRepo.getSignedUserSession() ?: return
        val startDateEn = Datetime.parseEnFormat(startDate).dateFormatEn()
        val endDateEn = Datetime.parseEnFormat(endDate).dateFormatEn()


        queryJob = viewModelScope.launch {
            val result = api.shiftChangeQueryList(
                userSession.userId,
                cloth,
                workshopId,
                startDateEn,
                endDateEn,
                fromMachine,
                toMachine
            )
            when (result) {
                is ApiCallResult.Success -> queryList.postValue(result.data!!)
                is ApiCallResult.Error -> _toastText.value = result.error
            }
        }

    }

    /**
     *  点击删除
     */
    fun onDeleteClick() {
        if (checkListForOperation().not()) return
        if (deleteJob?.isCompleted?.not() == true) return

        queryList.value?.also { list ->
            val remaining = mutableListOf<ShiftChangeQueryItem>()
            val deleting = mutableListOf<ShiftChangeQueryItem>()

            list.zip(queryItems.value!!) { a, b ->
                if (b.checked.get()) {
                    deleting.add(a)
                } else {
                    remaining.add(a)
                }
            }

            if (deleting.isEmpty()) return

            deleteJob = viewModelScope.launch {
                _loading.value = true
                when (val result = api.shiftChangeDeleteItem(deleting.map { it.primaryId })) {
                    is ApiCallResult.Success -> {
                        _toastText.value = "删除成功"
                        queryList.value = remaining
                    }
                    is ApiCallResult.Error -> {
                        _toastText.value = result.message
                    }
                }
                _loading.value = false
            }
        }
    }

    fun onSaveClick() {
        if (checkListForOperation().not()) return
        // 交班信息为空不能保存
        val hasEmptyInfoItem =
            queryItems.value?.any { it.checked.get() && emptyOrBlank(it.remark.get()) } ?: false

        if (hasEmptyInfoItem) {
            _toastText.value = "交班信息不能为空"
            return
        }


        if (saveJob?.isCompleted?.not() == true) return

        queryList.value?.also { _ ->

            val filter = queryItems.value!!.filter { it.checked.get() }
            val workshopId = getWorkshopId()
            val clothNo = getClothNo()

            if (filter.isEmpty()) return
            val userSession = userRepo.getSignedUserSession() ?: return

            saveJob = viewModelScope.launch {
                _loading.value = true

                val savingList = filter.map {
                    ShiftChangeSaveItem(
                        it.machineNo,
                        it.clothNo ?: "",
                        it.info,
                        it.remark.get() ?: "",
                        workshopId,
                        clothNo,
                        pkId = it.primaryId
                    )
                }

                when (val result =
                    api.shiftChangeRecordSave(
                        userSession.userId,
                        userSession.userName,
                        savingList
                    )) {
                    is ApiCallResult.Success -> {
                        _toastText.value = "保存成功"
                        _commonEvent.value = CommonEvent("set_all_check_status", false)
                    }
                    is ApiCallResult.Error -> {
                        _toastText.value = result.message
                    }
                }

                _loading.value = false
            }
        }

    }

    private fun checkListForOperation(): Boolean {
        if (queryItems.value == null) {
            _toastText.value = "列表为空"
            return false
        }

        if (queryItems.value!!.none { it.checked.get() }) {
            _toastText.value = "没有选择的条目"
            return false
        }
        return true
    }

    private fun getWorkshops() = viewModelScope.launch {
        when (val result = api.getWorkshopItems()) {
            is ApiCallResult.Success -> {
                val list = mutableListOf<WorkShopItem>()
                list.add(WorkShopItem("-1", "--请选择--"))
                list.addAll(result.data!!)
                _workshops.value = list
            }
            is ApiCallResult.Error -> {
                _toastText.value = result.error
            }
        }
    }

    private fun getWorkshopId(): String {
        return if (workshops.value == null || selectedWorkshopIndex.value!! <= 0) {
            ""
        } else {
            _workshops.value!![selectedWorkshopIndex.value!!].id
        }
    }

    private fun getClothNo(): String {
        return clothNo.value ?: ""
    }

    private fun emptyOrBlank(str: String?): Boolean {
        if (str == null) return true
        return str.trim().isEmpty()
    }
}